package com.xdf.whiteaccount.service.impl;

import com.xdf.whiteaccount.dao.BillCodeMapper;
import com.xdf.whiteaccount.enums.BillCodeResetEnum;
import com.xdf.whiteaccount.entity.BillCode;
import com.xdf.whiteaccount.utils.BusinessException;
import com.xdf.whiteaccount.utils.DatetimeUtils;
import com.xdf.whiteaccount.utils.StringUtils;
import com.xdf.whiteaccount.service.BillCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.Optional;

@Service
public class BillCodeServiceImpl implements BillCodeService {
    @Autowired
    private BillCodeMapper dao;

    @Override
    public int deleteByPrimaryKey(Integer iid) {
        return dao.deleteByPrimaryKey(iid);
    }

    // sid 保证唯一
    @Override
    public int insertSelective(BillCode record) {
        record = Optional.ofNullable(record).orElse(new BillCode());
        String sid = Optional.ofNullable(record.getSid()).orElse("");
        if(isExists(sid) == true) return 0;
        return dao.insertSelective(record);
    }

    @Override
    public BillCode selectByPrimaryKey(Integer iid) {
        return dao.selectByPrimaryKey(iid);
    }

    @Override
    public int updateByPrimaryKeySelective(BillCode record) {
        return dao.updateByPrimaryKeySelective(record);
    }

    @Override
    public BillCode selectBySid(String sid) {
        return dao.selectBySid(sid);
    }

    @Override
    public Boolean isExists(String sid) {
        BillCode billCode = selectBySid(sid);
        return billCode == null ? false : true;
    }

    @Override
    public String getNewBillCode(String sid) {
        return getNewBillCode(sid,BillCodeResetEnum.DAY);
//        if( sid == null || sid.length()<=0 ) return "";
//        // 如果当前没有该 sid 则创建新对象并返回
//        if(isExists(sid) == false) {
//            BillCode newOne = new BillCode();
//            newOne.setSid(sid);
//            newOne.setSeq_day(0);
//            newOne.setSeq_month(0);
//            newOne.setSeq_year(0);
//
//            Integer iid = insertSelective(newOne);
//        }
//
//        BillCode billCode = selectBySid(sid);
//        // 根据当前的日期累加 seq_day,seq_month,seq_year
//        billCode = increaseSeq(billCode);
//        dao.updateByPrimaryKeySelective(billCode);
//
//        Date billDate = Optional.ofNullable(billCode.getBill_date()).orElse(new Date());
//        String prefix = Optional.ofNullable(billCode.getPrefix()).orElse("");
//        String suffix = Optional.ofNullable(billCode.getSuffix()).orElse("");
//        Integer yearLength = Optional.ofNullable(billCode.getYear_length()).orElse(2);
//        Integer monthLength = Optional.ofNullable(billCode.getMonth_length()).orElse(2);
//        Integer dayLength = Optional.ofNullable(billCode.getDay_length()).orElse(2);
//
//        LocalDate localDate = date2LocalDate(billDate);
//        String yearString = String.valueOf(localDate.getYear()).substring(4-yearLength,4);
//
//        String monthString = monthLength > 0 ? String.valueOf(localDate.getMonthValue()):"";
//        if( monthString.length()>0 ) monthString = StringUtils.fillLength2(monthString);
//
//        String dayString = dayLength > 0 ? String.valueOf(localDate.getDayOfMonth()):"";
//        if(dayString.length()>0) dayString = StringUtils.fillLength2(dayString);
//
//        String dayNumberString = String.valueOf(billCode.getSeq_day());
//        int increaseLength = Optional.ofNullable(billCode.getIncrease_length()).orElse(3);
//        dayNumberString = StringUtils.fillToLength(dayNumberString,increaseLength,"0",true);
//
//        return prefix + yearString + monthString + dayString + dayNumberString + suffix;
    }

    /**
     * 传入的单据类型在 bill_code 中的行数据，对比当天的日期
     * 对3个 seq 进行累加
     * @param record 单据类型在表 bill_code 的行数据
     * @return 返回累加 seq 后的新对象
     */
    @Override
    public BillCode increaseSeq(BillCode record) {
        Date billDate = Optional.ofNullable(record.getBill_date()).orElse(new Date());
        boolean isToday = DatetimeUtils.isToday(billDate);
        boolean isThisMonth = DatetimeUtils.isThisMonth(billDate);
        boolean isThisYear = DatetimeUtils.isThisYear(billDate);

        Integer seqDay = Optional.ofNullable(record.getSeq_day()).orElse(0);
        Integer seqMonth = Optional.ofNullable(record.getSeq_month()).orElse(0);
        Integer seqYear = Optional.ofNullable(record.getSeq_year()).orElse(0);
        Integer seqNever = Optional.ofNullable(record.getSeq_never()).orElse(0);

        if( isToday == true ) record.setSeq_day(seqDay+1);
        else record.setSeq_day(1);
        if( isThisMonth == true)  record.setSeq_month(seqMonth+1);
        else record.setSeq_month(1);
        if( isThisYear == true ) record.setSeq_year(seqYear+1);
        else record.setSeq_year(1);
        record.setSeq_never(seqNever+1);

        // 设置单据编号自增序号后要更新为最新日期
        record.setBill_date(new Date());
        return record;
    }

    public static LocalDate date2LocalDate(Date date) {
        if(null == date) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    @Override
    public String getNewBillCode(String sid, BillCodeResetEnum resetEnum){
        if( sid == null || sid.length()<=0 ) return "";
        // 如果当前没有该 sid 则创建新对象并返回
        if(isExists(sid) == false) {
            BillCode newOne = new BillCode();
            newOne.setSid(sid);
            newOne.setSeq_day(0);
            newOne.setSeq_month(0);
            newOne.setSeq_year(0);

            Integer iid = insertSelective(newOne);
        }

        BillCode billCode = selectBySid(sid);
        // 根据当前的日期累加 seq_day,seq_month,seq_year
        billCode = increaseSeq(billCode);
        dao.updateByPrimaryKeySelective(billCode);

        Date billDate = Optional.ofNullable(billCode.getBill_date()).orElse(new Date());
        String prefix = Optional.ofNullable(billCode.getPrefix()).orElse("");
        String suffix = Optional.ofNullable(billCode.getSuffix()).orElse("");
        Integer yearLength = Optional.ofNullable(billCode.getYear_length()).orElse(2);
        Integer monthLength = Optional.ofNullable(billCode.getMonth_length()).orElse(2);
        Integer dayLength = Optional.ofNullable(billCode.getDay_length()).orElse(2);

        LocalDate localDate = date2LocalDate(billDate);
        String yearString = String.valueOf(localDate.getYear()).substring(4-yearLength,4);

        String monthString = monthLength > 0 ? String.valueOf(localDate.getMonthValue()):"";
        if( monthString.length()>0 ) monthString = StringUtils.fillLength2(monthString);

        String dayString = dayLength > 0 ? String.valueOf(localDate.getDayOfMonth()):"";
        if(dayString.length()>0) dayString = StringUtils.fillLength2(dayString);

        if(resetEnum == null) throw new BusinessException("必须传入单据编号自增重置种子！");
        String autoIncrNumberString = "";
        if(resetEnum == BillCodeResetEnum.DAY)
            autoIncrNumberString = String.valueOf(billCode.getSeq_day());
        if(resetEnum == BillCodeResetEnum.MONTH)
            autoIncrNumberString = String.valueOf(billCode.getSeq_month());
        if(resetEnum == BillCodeResetEnum.YEAR)
            autoIncrNumberString = String.valueOf(billCode.getSeq_year());
        if(resetEnum == BillCodeResetEnum.NEVER)
            autoIncrNumberString = String.valueOf(billCode.getSeq_never());
        int increaseLength = Optional.ofNullable(billCode.getIncrease_length()).orElse(3);
        autoIncrNumberString = StringUtils.fillToLength(autoIncrNumberString,increaseLength,"0",true);

        return prefix + yearString + monthString + dayString + autoIncrNumberString + suffix;
    }
}
